home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH10 / SRC / BEZIER.CLS < prev    next >
Text File  |  1996-05-04  |  11KB  |  380 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "ObjBezier"
  6. Attribute VB_Creatable = False
  7. Attribute VB_Exposed = False
  8. Option Explicit
  9.  
  10. Private MaxU As Integer     ' Dimensions of control grid.
  11. Private MaxV As Integer
  12. Private Points() As Point3D ' Control points.
  13.  
  14. ' grid holds a refined grid to display the surface.
  15. Private grid As ObjPicture
  16.  
  17. ' u and v increment parameters.
  18. Private GapU As Single
  19. Private GapV As Single
  20. Private Du As Single
  21. Private Dv As Single
  22.  
  23. ' Display flags.
  24. Private ShowControls As Boolean ' Draw control points?
  25. Private ShowGrid As Boolean     ' Draw control grid?
  26.  
  27. Function Factorial(ByVal n As Single) As Single
  28. Dim i As Integer
  29. Dim tot As Single
  30.  
  31.     tot = 1
  32.     For i = 2 To n
  33.         tot = tot * i
  34.     Next i
  35.     Factorial = tot
  36. End Function
  37.  
  38. ' ************************************************
  39. ' Create the refined grid to display the surface.
  40. ' ************************************************
  41. Public Sub InitializeGrid(gap_x As Single, gap_z As Single, d_x As Single, d_z As Single)
  42. Dim u As Single
  43. Dim v As Single
  44. Dim x As Single
  45. Dim y As Single
  46. Dim z As Single
  47. Dim x1 As Single
  48. Dim y1 As Single
  49. Dim z1 As Single
  50. Dim pline As ObjPolyline
  51.  
  52.     GapU = gap_x
  53.     GapV = gap_z
  54.     Du = d_x
  55.     Dv = d_z
  56.     
  57.     Set grid = New ObjPicture
  58.     
  59.     ' Create curves with constant u.
  60.     For u = 0 To 1 + GapU / 10 Step GapU
  61.         Set pline = New ObjPolyline
  62.         grid.objects.Add pline
  63.         
  64.         SurfaceValue u, 0, x1, y1, z1
  65.         
  66.         For v = Dv To 1 + Dv / 10 Step Dv
  67.             SurfaceValue u, v, x, y, z
  68.             pline.AddSegment x1, y1, z1, x, y, z
  69.             x1 = x
  70.             y1 = y
  71.             z1 = z
  72.         Next v
  73.     Next u
  74.  
  75.     ' Create curves with constant v.
  76.     For v = 0 To 1 + GapV / 10 Step GapV
  77.         Set pline = New ObjPolyline
  78.         grid.objects.Add pline
  79.         
  80.         SurfaceValue 0, v, x1, y1, z1
  81.         For u = Du To 1 + Du / 10 Step Du
  82.             SurfaceValue u, v, x, y, z
  83.             pline.AddSegment x1, y1, z1, x, y, z
  84.             x1 = x
  85.             y1 = y
  86.             z1 = z
  87.         Next u
  88.     Next v
  89. End Sub
  90. ' ************************************************
  91. ' Apply a transformation matrix which may not
  92. ' contain 0, 0, 0, 1 in the last column to the
  93. ' object.
  94. ' ************************************************
  95. Public Sub ApplyFull(M() As Single)
  96. Dim i As Integer
  97. Dim j As Integer
  98.     
  99.     ' Apply the matrix to the grid if it exists.
  100.     If Not grid Is Nothing Then grid.ApplyFull M
  101.  
  102.     ' Apply the matrix to the control points.
  103.     For i = 0 To MaxU
  104.         For j = 0 To MaxV
  105.             m3ApplyFull Points(i, j).coord, M, Points(i, j).trans
  106.         Next j
  107.     Next i
  108. End Sub
  109. ' ************************************************
  110. ' Apply a nonlinear transformation.
  111. ' ************************************************
  112. Public Sub Distort(D As Object)
  113. Dim i As Integer
  114. Dim j As Integer
  115.     
  116.     ' Distort the grid if it exists.
  117.     If Not grid Is Nothing Then grid.Distort D
  118.  
  119.     ' Distort the sparse data.
  120.     For i = 0 To MaxU
  121.         For j = 0 To MaxV
  122.             D.Distort Points(i, j).coord(1), Points(i, j).coord(2), Points(i, j).coord(3)
  123.         Next j
  124.     Next i
  125. End Sub
  126. ' ************************************************
  127. ' Draw the transformed object on a Form, Printer,
  128. ' or PictureBox.
  129. ' ************************************************
  130. Public Sub Draw(canvas As Object, Optional r As Variant)
  131. Dim i As Integer
  132. Dim j As Integer
  133.     
  134.     ' Draw the grid if it exists.
  135.     If Not grid Is Nothing Then grid.Draw canvas, r
  136.  
  137.     ' Draw the control points if desired.
  138.     If ShowControls Then
  139.         On Error Resume Next
  140.         For i = 0 To MaxU
  141.             For j = 0 To MaxV
  142.                 canvas.Line (Points(i, j).trans(1) - 2, Points(i, j).trans(2) - 2)-Step(4, 4), , BF
  143.             Next j
  144.         Next i
  145.     End If
  146.  
  147.     ' Draw the control grid if desired.
  148.     If ShowGrid Then
  149.         On Error Resume Next
  150.         For i = 0 To MaxU
  151.             canvas.CurrentX = Points(i, 0).trans(1)
  152.             canvas.CurrentY = Points(i, 0).trans(2)
  153.             For j = 1 To MaxV
  154.                 canvas.Line -(Points(i, j).trans(1), Points(i, j).trans(2))
  155.             Next j
  156.         Next i
  157.         For j = 0 To MaxV
  158.             canvas.CurrentX = Points(0, j).trans(1)
  159.             canvas.CurrentY = Points(0, j).trans(2)
  160.             For i = 1 To MaxU
  161.                 canvas.Line -(Points(i, j).trans(1), Points(i, j).trans(2))
  162.             Next i
  163.         Next j
  164.     End If
  165. End Sub
  166.  
  167. ' ************************************************
  168. ' Read a Bezier surface from a file using Input.
  169. ' Assume the "BEZIER" label has already been
  170. ' read.
  171. ' ************************************************
  172. Public Sub FileInput(filenum As Integer)
  173. Dim i As Integer
  174. Dim j As Integer
  175.  
  176.     ' Get the basic information.
  177.     Input #filenum, MaxU, MaxV, GapU, GapV, Du, Dv
  178.     
  179.     ' Allocate the Data array.
  180.     SetBounds MaxU + 1, MaxV + 1
  181.     
  182.     ' Read the control points.
  183.     For i = 0 To MaxU
  184.         For j = 0 To MaxV
  185.             Input #filenum, _
  186.                 Points(i, j).coord(1), _
  187.                 Points(i, j).coord(2), _
  188.                 Points(i, j).coord(3)
  189.             Points(i, j).coord(4) = 1
  190.         Next j
  191.     Next i
  192.     
  193.     ' Initialize the grid data.
  194.     If Du = 0 Then
  195.         Set grid = Nothing
  196.     Else
  197.         InitializeGrid GapU, GapV, Du, Dv
  198.     End If
  199. End Sub
  200.  
  201.  
  202.  
  203.  
  204. ' ************************************************
  205. ' Write a Bezier surface to a file using Write.
  206. ' Begin with "BEZIER" to identify this object.
  207. ' ************************************************
  208. Public Sub FileWrite(filenum As Integer)
  209. Dim i As Integer
  210. Dim j As Integer
  211.  
  212.     ' Write basic information.
  213.     Write #filenum, "BEZIER", _
  214.         MaxU, MaxV, GapU, GapV, Du, Dv
  215.         
  216.     ' Write the data.
  217.     For i = 0 To MaxU
  218.         For j = 0 To MaxV
  219.             Write #filenum, _
  220.                 Points(i, j).coord(1), _
  221.                 Points(i, j).coord(2), _
  222.                 Points(i, j).coord(3)
  223.         Next j
  224.     Next i
  225. End Sub
  226. ' ************************************************
  227. ' Write the Bezier curve's grid object to a file
  228. ' using Write. The data can later be loaded into
  229. ' an ObjPicture object but not an ObjBezier
  230. ' object.
  231. ' ************************************************
  232. Public Sub FileWriteGrid(filenum As Integer)
  233.     If Not grid Is Nothing Then grid.FileWrite filenum
  234. End Sub
  235.  
  236. ' ***********************************************
  237. ' Fix the data coordinates at their transformed
  238. ' values.
  239. ' ***********************************************
  240. Public Sub FixPoints()
  241. Dim i As Integer
  242. Dim j As Integer
  243. Dim k As Integer
  244.  
  245.     ' Fix the grid points if the grid exists.
  246.     If Not grid Is Nothing Then grid.FixPoints
  247.  
  248.     ' Fix the controls points.
  249.     For i = 0 To MaxU
  250.         For j = 0 To MaxV
  251.             For k = 1 To 3
  252.                 Points(i, j).coord(k) = _
  253.                     Points(i, j).trans(k)
  254.             Next k
  255.         Next j
  256.     Next i
  257. End Sub
  258.  
  259.  
  260. ' ***********************************************
  261. ' Return a string indicating the object type.
  262. ' ***********************************************
  263. Property Get ObjectType() As String
  264.     ObjectType = "BEZIER"
  265. End Property
  266. ' ************************************************
  267. ' Let the user know if we are drawing the control
  268. ' grid.
  269. ' ************************************************
  270. Property Get DrawGrid() As Boolean
  271.     DrawGrid = ShowGrid
  272. End Property
  273.  
  274. ' ************************************************
  275. ' Let the user know if we are drawing the control
  276. ' points.
  277. ' ************************************************
  278. Property Get DrawControls() As Boolean
  279.     DrawControls = ShowControls
  280. End Property
  281.  
  282.  
  283. ' ************************************************
  284. ' Let the user decide whether we should draw the
  285. ' control grid.
  286. ' ************************************************
  287. Property Let DrawGrid(value As Boolean)
  288.     ShowGrid = value
  289. End Property
  290. ' ************************************************
  291. ' Let the user decide whether we should draw the
  292. ' control points.
  293. ' ************************************************
  294. Property Let DrawControls(value As Boolean)
  295.     ShowControls = value
  296. End Property
  297.  
  298.  
  299.  
  300.  
  301. ' ************************************************
  302. ' Apply a transformation matrix to the object.
  303. ' ************************************************
  304. Public Sub Apply(M() As Single)
  305. Dim i As Integer
  306. Dim j As Integer
  307.     
  308.     ' Apply the matrix to the grid if it exists.
  309.     If Not grid Is Nothing Then grid.Apply M
  310.  
  311.     ' Apply the matrix to the control points.
  312.     For i = 0 To MaxU
  313.         For j = 0 To MaxV
  314.             m3Apply Points(i, j).coord, M, Points(i, j).trans
  315.         Next j
  316.     Next i
  317. End Sub
  318.  
  319.  
  320.  
  321.  
  322.  
  323. ' ************************************************
  324. ' Set MaxU and MaxV ans allocate room for the
  325. ' control points.
  326. ' ************************************************
  327. Public Sub SetBounds(NumX As Integer, NumZ As Integer)
  328.     MaxU = NumX - 1
  329.     MaxV = NumZ - 1
  330.     ReDim Points(0 To NumX, 0 To NumZ)
  331. End Sub
  332.  
  333. ' ************************************************
  334. ' Set the value for a control point.
  335. ' ************************************************
  336. Public Sub SetControlPoint(i As Integer, j As Integer, x As Single, y As Single, z As Single)
  337.     Points(i - 1, j - 1).coord(1) = x
  338.     Points(i - 1, j - 1).coord(2) = y
  339.     Points(i - 1, j - 1).coord(3) = z
  340.     Points(i - 1, j - 1).coord(4) = 1
  341. End Sub
  342. ' ************************************************
  343. ' Return the value of the Bezier surface at this
  344. ' position.
  345. ' ************************************************
  346. Private Sub SurfaceValue(u As Single, v As Single, x As Single, y As Single, z As Single)
  347. Dim p As Integer
  348. Dim i As Integer
  349. Dim j As Integer
  350. Dim pt As Point3D
  351. Dim Bix As Single
  352. Dim Bjz As Single
  353.  
  354.     For i = 0 To MaxU
  355.         ' Compute Bix.
  356.         Bix = Factorial(MaxU) / Factorial(i) / _
  357.             Factorial(MaxU - i) * _
  358.             u ^ i * (1 - u) ^ (MaxU - i)
  359.         
  360.         For j = 0 To MaxV
  361.             ' Compute Bjz.
  362.             Bjz = Factorial(MaxV) / Factorial(j) / _
  363.                 Factorial(MaxV - j) * _
  364.                 v ^ j * (1 - v) ^ (MaxV - j)
  365.             
  366.             ' Add to the coordinates.
  367.             For p = 1 To 3
  368.                 pt.coord(p) = pt.coord(p) + _
  369.                     Points(i, j).coord(p) * _
  370.                     Bix * Bjz
  371.             Next p
  372.         Next j
  373.     Next i
  374.     
  375.     ' Prepare the output.
  376.     x = pt.coord(1)
  377.     y = pt.coord(2)
  378.     z = pt.coord(3)
  379. End Sub
  380.